import G6 from '@antv/g6'
import { getStructure } from '@/services/zhirong/visualAnalysis';
import ProCard from '@ant-design/pro-card';
import Graphin, { Behaviors } from '@antv/graphin';
import { useRequest } from '@umijs/hooks';
import { Tag, Tooltip, Divider } from 'antd';
import { createRef, useEffect, useState, useContext } from 'react';
import GraphLayout from '@/components/graphLayout';
import { OptionToolbarTwo } from '@/components/Toolbar';
import VisualAnalysisLayout from '../VisualAnalysisLayout ';
import { QuestionCircleOutlined } from '@ant-design/icons';
import classes from './index.module.css'


const StructureGraph = () => {
  const { ZoomCanvas, ActivateRelations, DragCanvas } = Behaviors;

  const description = {
    SCC: {
      head: '强连通核(Strongly connected core,SCC)',
      text: '也称为强连通巨片(Giantstrongly connected component)，它位于网络的中心。SCC中任意两个节点之间都是强连通的，即存在从任一节点到另一节点的有向路径。',
      color: '#FF0000',
      fill: '#FFCECE',
      key: 1,
    },
    IN: {
      head: '入部(IN)',
      text: `包含那些可以通过有向路径到达SCC但不能从SCC到达的节点。
也就是说，一定存在从IN中任一节点到SCC中任一节点的有向路径；反之，从SCC中任一节点出发沿着有向边都无法到达IN中的一个节点。`,
      color: '#722ED1',
      fill: '#F3E3FF',
      outline: '',
      key: 2,
    },
    OUT: {
      head: '出部(OUT)',
      text: `包含那些可以从SCC通过有向路径到达但不能到达SCC的节点。
也就是说，一定存在从SCC中任一节点到OUT中任一节点的有向路径；反之，从OUT中任一节点出发沿着有向边都无法到达SCC中的一个节点。
从IN中任一节点到OUT中任一节点必然存在有向路径，而且该路径必经过SCC中的某些节点。`,
      color: '#2F54EB',
      fill: '#D6E4FF',
      key: 3,
    },
    INTENDRILS: {
      head: '卷须(Tendrils)',
      text: `包含那些既无法到达SCC也无法从SCC到达的节点。
对于挂在IN上的任一卷须节点，必至少存在一条从IN中某一节点到该节点的不需经过SCC的有向路径；
对于挂在OUT上的任一卷须节点，必至少存在一条从该节点到OUT中某一节点的不需经过SCC的有向路径。`,
      color: '#A0D911',
      fill: '#F4FFB8',
      key: 4,
    },
    OUTTENDRILS: {
      head: '卷须(Tendrils )',
      text: `包含那些既无法到达SCC也无法从SCC到达的节点。
对于挂在IN上的任一卷须节点，必至少存在一条从IN中某一节点到该节点的不需经过SCC的有向路径；
对于挂在OUT上的任一卷须节点，必至少存在一条从该节点到OUT中某一节点的不需经过SCC的有向路径。`,
      color: '#ffca28',
      fill: '#F5DEB3',
      key: 5,
    },
    TUBES: {
      head: '管子(Tube)',
      text: `此外，还有可能存在从挂在IN上的卷须节点到挂在OUT上的卷须节点的不经过SCC的有向路径，这些串在一起的卷须节点称为管子(Tube)。`,
      color: '#13C2C2',
      fill: '#B5F5EC',
      key: 6,
    },
    OTHER: {
      head: '其他',
      text: `其他节点`,
      color: '#808080',
      fill: '#FCFCFC',
      key: 6,
    }
  };

  // 图例的样式
  const typeConfigs = {
    'INTENDRILS': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#A0D911',
        fill: '#F4FFB8',
        lineWidth: 1,
      }
    },
    'OUTTENDRILS': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#13C2C2',
        fill: '#B5F5EC',
        lineWidth: 1,
      }
    },
    'TUBES': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#FAAD14',
        fill: '#FFF1B8',
        lineWidth: 1,
      }
    },
    'SCC': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#FF0000',
        fill: '#FFCECE',
        lineWidth: 1,
      }
    },
    'IN': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#722ED1',
        fill: '#F3E3FF',
        lineWidth: 1,
      }
    },
    'OUT': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#2F54EB',
        fill: '#D6E4FF',
        lineWidth: 1,
      }
    },
    'OTHER': {
      type: 'circle',
      size: 14,
      style: {
        stroke: '#808080',
        fill: '#FCFCFC',
        lineWidth: 1,
      }
    }
  }

  //图例信息
  const legendData = {
    nodes: [{
      id: 'INTENDRILS',
      label: 'IN-TENDRILS卷须',
      order: '5',
      ...typeConfigs['INTENDRILS']
    },
    {
      id: 'OUTTENDRILS',
      label: 'OUT-TENDRILS卷须',
      order: '4',
      ...typeConfigs['OUTTENDRILS']
    },
    {
      id: 'TUBES',
      label: '管子（TUBES)',
      order: '3',
      ...typeConfigs['TUBES']
    },
    {
      id: 'OUT',
      label: '出部（OUT）',
      order: '2',
      ...typeConfigs['OUT']
    },
    {
      id: 'IN',
      label: '入部（IN）',
      order: '1',
      ...typeConfigs['IN']
    },
    {
      id: 'SCC',
      label: '强连通核（SCC）',
      order: '0',
      ...typeConfigs['SCC']
    },
    {
      id: 'OTHER',
      label: '其他',
      order: '6',
      ...typeConfigs['OTHER']
    }]
  }

  //图例画布
  const legend = new G6.Legend({
    data: legendData,
    //画布本身的位置
    position: 'top',
    // margin: '3em',
    //图例内部元素的位置
    padding: [8, 8, 8, 8],
    containerStyle: {
      fill: '#fff',
      lineWidth: 0,
    },
    // title: '点击图例上的元素进行筛选',
    // titleConfig: {
    //   position: 'center',
    //   fontSize: "10px",
    //   offsetX: 0,
    //   offsetY: 12,
    // },
    filter: {
      enable: true,
      multiple: true,
      trigger: 'click',
      graphActiveState: 'activeByLegend',
      graphInactiveState: 'inactiveByLegend',
      filterFunctions: {
        'INTENDRILS': (d) => {
          if (d.legendType === 'INTENDRILS') return true;
          return false
        },
        'OUTTENDRILS': (d) => {
          if (d.legendType === 'OUTTENDRILS') return true;
          return false
        },
        'TUBES': (d) => {
          if (d.legendType === 'TUBES') return true;
          return false
        },
        'SCC': (d) => {
          if (d.legendType === 'SCC') return true;
          return false
        },
        'IN': (d) => {
          if (d.legendType === 'IN') return true;
          return false
        },
        'OUT': (d) => {
          if (d.legendType === 'OUT') return true;
          return false
        },
        'OTHER': (d) => {
          if (d.legendType === 'OTHER') return true;
          return false
        },
      }
    }

  })
  //选中和未选中的样式
  const AnimateStyle = {
    defaultNode: {
      size: 20,
      style: {
        lineWidth: 2,
      }

    },
    defaultEdge: {
      size: 1,
      color: "#e2e2e2",
      style: {
        endArrow: {
          path: 'M 0,0 L 8,4 L 8,-4 Z',
          fill: '#e2e2e2',
        }
      }
    },
    nodeStateStyles: {
      status: {
        hover: {
          halo: {
            visible: true,
          }
        }
      },
      activeByLegend: {
        lineWidth: 3,
        strokeOpacity: 0.5,
        stroke: '#42a5f5'
      },
      inactiveByLegend: {
        opacity: 0.1,
      }
    },
    edgeStateStyles: {
      activeByLegend: {
        lineWidth: 10,
        strokeOpacity: 0.5
      },
      inactiveByLegend: {
        opacity: 0.5
      }
    },
    nodeStyle: {
      select: {
        fill: '#ccc',
      }
    }
  }

  const layout = {
    type: 'force',
    preventOverlap: true,
    clustering: true,
    clusterNodeStrength: -5,
    clusterEdgeDistance: 200,
    clusterNodesize: 14,
    clusterFociStrength: 1.2,
    nodeSpacing: 5,
  };
  const [search, setSearch] = useState({ eid: 'fa65c5e6-c5e9-11e7-a96b-00163e1254b5' });
  const graphRef = createRef();
  const shouldBegin = () => {
    return true;
  }
  const [currentHover, setHover] = useState();
  const [graph, setGraph] = useState({
    nodes: [],
    edges: [],
  });
  const [data, setData] = useState({
    SCC: 0,
    IN: 0,
    OUT: 0,
    INTENDRILS: 0,
    OUTTENDRILS: 0,
    TUBES: 0,
    Total: 0,
  });
  const [loading, setLoading] = useState(false);
  const refresh = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 0);
  };
  const { run, loading: loadingGraph } = useRequest(getStructure, {
    onSuccess: (res) => {
      if (!res.data) return;
      console.log('我是完整的数据', res.data)
      const { nodes, links } = res.data[0] ? res.data[0] : res.data;
      const edges = [];
      const cates = [];
      const ids = nodes.map((node) => node.id);
      links.forEach((link) => {
        if (ids.indexOf(link.source) !== -1 && ids.indexOf(link.target) !== -1) {
          edges.push(link);
        }
      });
      nodes.forEach((node) => {
        //加入图例类型
        node.legendType = node.belong;
        node.style = {
          keyshape: {
            stroke: description[node.belong]?.color,
            fill: description[node.belong]?.fill,
            size: node.belong === 'SCC' ? 23 : 20,
          },
          label: {
            value: node.belong === 'SCC' ? node.name : '',
          },
        };
        node.comboId = node.belong;
        node.cluster = description[node.belong]?.key;

        //给node加相应的typeConfigs
        if (!node.legendType) return;
        node = Object.assign(node, { ...typeConfigs[node.legendType] });
        if (!cates.includes(node.belong)) {
          cates.push(node.belong);
        }
      });
      const combos = cates.map((cate) => {
        return {
          id: cate,
          label: cate,
        };
      });


      console.log(nodes);
      setGraph({ nodes, edges, combos });
      setData((prev) => {
        const ret = { ...prev };
        Object.keys(prev).forEach((key) => {
          ret[key] = nodes.filter((e) => e.belong === key).length;
        });
        ret.Total = nodes.length;
        return ret;
      });
    },
  });
  useEffect(() => {
    if (graphRef.current) {
      graphRef.current.graph.on('node:click', (node) => {
        // eslint-disable-next-line no-underscore-dangle
        setHover(node.item._cfg.model.belong);
      });
    }
  });
  useEffect(() => {
    console.log("graph", graph);
  }, [graph]);
  useEffect(() => {
    run({
      entityA: search.eid,
    });
  }, [search, run]);

  return (
    <VisualAnalysisLayout title="交叉持股发现" onSubmit={setSearch}>
      <GraphLayout
        leftSpan={19}
        rightSpan={5}
        leftChildren={
          <ProCard loading={loading || loadingGraph} style={{ height: '100vh', width: '100%', borderRadius: '8px', }}>
            <Graphin
              plugins={[legend]}
              data={graph}
              ref={graphRef}
              defaultNode={AnimateStyle.defaultNode}
              nodeStateStyles={AnimateStyle.nodeStateStyles}
              defaultEdge={AnimateStyle.defaultEdge}
              layout={layout}
              style={{ height: '100%', width: '100%' }}
              fitview
            >
              <ZoomCanvas />
              <OptionToolbarTwo direction={'horizontal'} refresh={refresh} />
              {/* <ActivateRelations trigger="click"> </ActivateRelations> */}
              <DragCanvas shouldBegin={shouldBegin} ></DragCanvas>
            </Graphin>
          </ProCard>
        }
        rightChildren={
          <ProCard style={{ borderRadius: '8px', height: '100vh' }} >
            <h2 className={classes.h2}>交叉持股信息</h2>
            <h4>该网络2018年存在交叉持股。</h4>
            <a>查看前序关联关系</a>
            <a>查看后续关联关系</a>
            <Divider className={classes.divider} />
            <h2 className={classes.a}>网络信息</h2>
            <p style={{ fontSize: '10px', marginTop: '-1em', marginBottom: '1em', color: "#bbb" }}>* 点击图例上的节点进行筛选</p>
            <span className={classes.subTitle}> 强连通核（SCC）
              <Tooltip title={
                <div classes={classes.descBox}>
                  <div className={classes.descHead}>{description["SCC"]?.head}</div>
                  <p>{description["SCC"]?.text}</p>
                </div>}>
                <QuestionCircleOutlined style={{ color: '#999999', fontSize: '14px' }} />
              </Tooltip>
            </span>
            <p> 数量：{data.SCC} </p>
            <p>占比： {((data.SCC / data.Total) * 100).toFixed(1)}%</p>
            <Divider className={classes.divider} />
            <span className={classes.subTitle}> 入部（IN）
              <Tooltip title={
                <div classes={classes.descBox}>
                  <div className={classes.descHead}>{description["IN"]?.head}</div>
                  <p>{description["IN"]?.text}</p>
                </div>}>
                <QuestionCircleOutlined style={{ color: '#999999', fontSize: '14px' }} />
              </Tooltip>
            </span >
            <p> 数量：{data.IN} </p>
            <p>占比： {((data.IN / data.Total) * 100).toFixed(1)}%</p>
            <br />
            <span className={classes.subTitle}> 出部（OUT）
              <Tooltip title={
                <div classes={classes.descBox}>
                  <div className={classes.descHead}>{description["OUT"]?.head}</div>
                  <p>{description["OUT"]?.text}</p>
                </div>}>
                <QuestionCircleOutlined style={{ color: '#999999', fontSize: '14px' }} />
              </Tooltip>
            </span>
            <p> 数量：{data.OUT}</p>
            <p> 占比： {((data.OUT / data.Total) * 100).toFixed(1)}%</p>
            <Divider className={classes.divider} />
            <span className={classes.subTitle}> 卷须（Tendrils）
              <Tooltip title={
                <div classes={classes.descBox}>
                  <div className={classes.descHead}>{description["INTENDRILS"]?.head}</div>
                  <p>{description["INTENDRILS"]?.text}</p>
                </div>}>
                <QuestionCircleOutlined style={{ color: '#999999', fontSize: '14px' }} />
              </Tooltip>
            </span>
            <div className={classes.TendrilsBox}>
              <div>
                <p>IN-Tendrils</p>
                <p>数量：{data.INTENDRILS}</p>
                <p>占比：{((data.INTENDRILS / data.Total) * 100).toFixed(1)}%</p>
              </div>
              <div>
                <p>OUT-Tendrils</p>
                <p>数量{data.OUTTENDRILS}</p>
                <p>占比： {((data.OUTTENDRILS / data.Total) * 100).toFixed(1)}%</p>
              </div>
            </div>

            <Divider className={classes.divider} />
            <span className={classes.subTitle}> 管子（Tubes）
              <Tooltip title={
                <div classes={classes.descBox}>
                  <div className={classes.descHead}>{description["TUBES"]?.head}</div>
                  <p>{description["TUBES"]?.text}</p>
                </div>}>
                <QuestionCircleOutlined style={{ color: '#999999', fontSize: '14px' }} />
              </Tooltip>
            </span>
            <p> 数量：{data.TUBES} </p>
            <p>占比：{((data.TUBES / data.Total) * 100).toFixed(1)}%</p>
          </ProCard>
        }
      ></GraphLayout >

    </VisualAnalysisLayout >
  );
};

export default StructureGraph;